package cn.fl.institution.service.impl;

import cmm.mid.core.framework.dto.MessageDTO;
import cmm.mid.core.framework.page.DataResultVO;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.fl.customer.service.ICstBankService;
import cn.fl.customer.vo.CstBankVO;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.institution.service.ICstBscInfoInsCzbankService;
import cn.fl.project.condition.PrjCstAccInfoQueryCondition;
import cn.fl.project.constant.PrjBscInfoConstant;
import cn.fl.project.service.IPrjBscInfoService;
import cn.fl.project.service.IPrjCstAccInfoService;
import cn.fl.project.vo.PrjCstAccInfoVO;
import cn.fl.system.constant.SysInsCfgInfoConstant;
import com.alibaba.fastjson.JSON;
import fl.customer.facade.customer.condition.CstBankQueryCondition;
import fl.czbank.facade.api.ICzbankApi;
import fl.ref.fribaseinfo.service.IBankAccInfoApiService;
import fl.ref.fribaseinfo.service.IFriBaseInfoApiService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tc.esign.facade.esign.api.ICfcaUsrApiService;
import tc.esign.facade.esign.dto.CfcaUsrDTO;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class CstBscInfoInsCzbankServiceImpl implements ICstBscInfoInsCzbankService {

    @SuppressWarnings("unused")
    private static final Logger logger = LoggerFactory.getLogger(CstBscInfoInsCzbankServiceImpl.class);

    @Autowired
    private IPrjBscInfoService prjBscInfoService; // 项目基础信息表
    @Autowired
    private IPrjCstAccInfoService prjCstAccInfoService;
    @Autowired
    private IFriBaseInfoApiService friBaseInfoApiService;
    @Autowired
    private IBankAccInfoApiService bankAccInfoApiService;
    /**
     * CstBank 服务层BEAN
     */
    @Autowired
    private ICstBankService cstBankService;
    @Autowired
    private ICfcaUsrApiService cfcaUsrApiService;
    @Autowired
    private ICzbankApi czbankApi;

    @Override
    public DataResultVO getChangeBankCardSMSCode(String cstId, String bankId) throws BaseException {
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, "成功!");
        Boolean audStsCd = false ; //默认4要素验证 未验证活失败
        if (StringUtils.isEmpty(cstId)) {
            BaseLogUtils.info(logger, "getChangeBankCardSMSCode", "客户ID不能为空", CurrentThreadContext.getCurrentUserName());
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "客户ID未空");
        }
        if (StringUtils.isEmpty(bankId)) {
            BaseLogUtils.info(logger, "getChangeBankCardSMSCode", "银行ID不能为空", CurrentThreadContext.getCurrentUserName());
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "银行ID未空");
        }
        if (StringUtils.isEmpty(bankId)) {
            BaseLogUtils.info(logger, "getChangeBankCardSMSCode", "银行ID不能为空", CurrentThreadContext.getCurrentUserName());
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "银行ID未空");
        }
        try {
            // 查询机构信息 -- 浙商
            /*
            不要删
            FriBaseInfoQueryCondition qc = new FriBaseInfoQueryCondition();
            qc.setInsCode(PrjBscInfoConstant.PRJ_INS_CODE_ZS); // 浙商
            qc.setInsSts(FriBaseInfoConstant.FRI_BASE_INFO_INS_STS_PASS);
            qc.setInsUseCd("2");
            qc.setSysCd(CurrentThreadContext.getCurrentSysCd());
            qc.setOrgCd(CurrentThreadContext.getCurrentOrgCd());
            List<FriBaseInfoDTO> prjBaseInfoDot = this.friBaseInfoApiService.searchList(qc);
            if (CollectionUtils.isEmpty(prjBaseInfoDot)) {
                BaseLogUtils.info(logger, "getChangeBankCardSMSCode", "获取金融机构未空custId" + cstId);
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "获取金融机构失败");
            }
            FriBaseInfoDTO prjbaseinfo = prjBaseInfoDot.get(0);*/
            // TODO 浙商  换绑卡获取短信  查询项目
           /*
           不要删除
           PrjBscInfoQueryCondition prjQc = new PrjBscInfoQueryCondition();
            prjQc.setInsCode(PrjBscInfoConstant.PRJ_INS_CODE_ZS);
            prjQc.setCstId(Long.valueOf(cstId));
            List<PrjBscInfoVO> prjBscInfoList = this.prjBscInfoService.searchPrjBscInfoList(prjQc);
            if(CollectionUtils.isEmpty(prjBscInfoList)){
                BaseLogUtils.info(logger,"getChangeBankCardSMSCode","未获取浙商项目 prjQc="+ JSON.toJSONString(prjQc),CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "未获取浙商项目");
            }
            PrjBscInfoVO prj = null ;
            Boolean hasStsCdIs2 = false ; //是否存在审核通过的项目 默认false
            for(PrjBscInfoVO prjbscinfo : prjBscInfoList){
                //默认取审核通过的项目进行查询
                if("2".equals(prjbscinfo.getPrjStsCd())){
                    prj = prjbscinfo ;
                    hasStsCdIs2 = true ;
                    break;
                }
            }
            //如果没有审核通过的项目 取第一个项目
            if(null == prj || !hasStsCdIs2){
                prj = prjBscInfoList.get(0);
            }*/

            List<Map<String, Object>> mapList = this.prjBscInfoService.selectChangeBankCardPrjPaySchInfo(null, Long.valueOf(cstId), PrjBscInfoConstant.PRJ_INS_CODE_ZS);
            if (CollectionUtils.isEmpty(mapList)) {
                BaseLogUtils.info(logger, "getChangeBankCardSMSCode", "未获取浙商项目信息cstId = " + cstId, CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "未获取浙商项目信息");
            }
            Map<String, Object> prjMap = mapList.get(0);
            if (StringUtils.isEmpty(String.valueOf(prjMap.get("PRJID")))) {
                BaseLogUtils.info(logger, "getChangeBankCardSMSCode", "未获取浙商项目信息cstId = " + cstId, CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "未获取浙商项目信息项目id");
            }
            Long prjId = Long.valueOf(String.valueOf(prjMap.get("PRJID")));
            if (StringUtils.isEmpty(String.valueOf(prjMap.get("MP")))) {
                BaseLogUtils.info(logger, "getChangeBankCardSMSCode", "未获取浙商项目信息MP = " + cstId, CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "未获取浙商项目信息手机号");
            }
            String MP = String.valueOf(prjMap.get("MP"));

           /*
           不要删
           PrjCstAccInfoQueryCondition prjAccQc = new PrjCstAccInfoQueryCondition();
            prjAccQc.setCstId(Long.valueOf(cstId));
            prjAccQc.setPrjId(prj.getId());
            List<PrjCstAccInfoVO> prjCstAccInfoList =  this.prjCstAccInfoService.searchList(prjAccQc);
            if(CollectionUtils.isEmpty(prjCstAccInfoList) || prjCstAccInfoList.size() == 0 ){
                BaseLogUtils.info(logger,"getChangeBankCardSMSCode","未获取项目客户信息",CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "未获取项目客户信息");
            }
            PrjCstAccInfoVO prjCstaccInfo = prjCstAccInfoList.get(0);
            */
            //获取用户４要素基本信息
            CstBankVO cstBank = this.cstBankService.selectById(Long.valueOf(bankId));
            if(null == cstBank){
                  BaseLogUtils.info(logger, "doCfcaAuth", "查询绑卡银行卡信息为空 bankId=" + JSON.toJSONString(cstBank));
                  return new DataResultVO(BaseConstant.IS_YESNO_NO, "查询绑卡银行卡信息为空");
            }
             BaseLogUtils.info(logger, "doCfcaAuth", "查询绑卡银行卡信息，有验证4要素结果" + JSON.toJSONString(cstBank));
            if(StringUtils.isEmpty(cstBank.getAudStsCd())){
                BaseLogUtils.info(logger, "doCfcaAuth", "查询绑卡银行卡信息AudStsCd为空 bankId=" + JSON.toJSONString(cstBank));
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "查询绑卡银行卡信息AudStsCd为空");
            }
            if(!cstBank.getAudStsCd().equals(SysInsCfgInfoConstant.CODE_CST_AUTH_RST_CD_1)){ // 如果未通过则需要验证4要素
                 //提供安心签的信息认证
                CfcaUsrDTO cfcaUsrDTO = new CfcaUsrDTO();
                cfcaUsrDTO.setPersonName(cstBank.getAccNm());
                cfcaUsrDTO.setIdentNo(cstBank.getCertNo());
                cfcaUsrDTO.setIdentTypeCode(cstBank.getCertTypCd());
                cfcaUsrDTO.setAuthenticationMode(SysInsCfgInfoConstant.CODE_CST_AUTH_CD_4);
                cfcaUsrDTO.setAccountNo(cstBank.getAccNo());
                cfcaUsrDTO.setIdentTypeCode("0");
                //如果需要校验4要素，添加手机号
                if (SysInsCfgInfoConstant.CODE_CST_AUTH_CD_4.equals(SysInsCfgInfoConstant.CODE_CST_AUTH_CD_4)) {
                    if (StringUtils.isBlank(cstBank.getCardTel())) {
                        BaseLogUtils.info(logger, "doCfcaAuth", "校验客户三/四要素参数不完整,手机号为空" + JSON.toJSONString(cstBank));
                        return new DataResultVO(BaseConstant.IS_YESNO_NO, "客户手机号为空");
                    }
                    cfcaUsrDTO.setPhoneNo(cstBank.getCardTel());
                }
                BaseLogUtils.info(logger, "doCfcaAuth", "客户几要素校验请求：" + JSON.toJSONString(cfcaUsrDTO));
                cfcaUsrDTO = this.cfcaUsrApiService.doCfcaAut(cfcaUsrDTO);
                BaseLogUtils.info(logger, "doCfcaAuth", "客户几要素校验返回：" + JSON.toJSONString(cfcaUsrDTO));
                if (null != cfcaUsrDTO && StringUtils.isNotEmpty(cfcaUsrDTO.getAuthenticationResu())) {
                    BaseLogUtils.info(logger, "doCfcaAuth", "校验结果：" + JSON.toJSONString(cfcaUsrDTO));
                   // if (true) { // TODO 浙商换绑卡 获取验证码 默认通过 方便测试
                    if("1".equals(String.valueOf(cfcaUsrDTO.getAuthenticationResu()))){
                        audStsCd = true ;
                        cstBank.setAudStsCd(SysInsCfgInfoConstant.CODE_CST_AUTH_RST_CD_1);
                        cstBank.setAudStsCdRem(cfcaUsrDTO.getRebackMessage().replace("/null",""));
                        this.cstBankService.modify(cstBank);
                        BaseLogUtils.info(logger, "doCfcaAuth", "校验结果-成功：" + JSON.toJSONString(cfcaUsrDTO));
                    } else {
                        cstBank.setAudStsCd(SysInsCfgInfoConstant.CODE_CST_AUTH_RST_CD_2);
                        cstBank.setAudStsCdRem(cfcaUsrDTO.getRebackMessage().replace("/null",""));
                        this.cstBankService.modify(cstBank);
                        BaseLogUtils.info(logger, "doCfcaAuth", "校验失败：" + JSON.toJSONString(cfcaUsrDTO));
                        return new DataResultVO(BaseConstant.IS_YESNO_NO, cfcaUsrDTO.getRebackMessage());
                    }

                } else {
                    BaseLogUtils.info(logger, "doCfcaAuth", "校验返回结果为空：" + JSON.toJSONString(cfcaUsrDTO));
                    return new DataResultVO(BaseConstant.IS_YESNO_NO, "校验返回结果为空");
                }
            }else{
                audStsCd = true;
            }
            // 验证结果
            if(audStsCd){
                MessageDTO messageDto = this.czbankApi.getChangeBankCardSMSCode(prjId, MP, cstBank.getAccNo());
                if (null == messageDto) {
                    BaseLogUtils.info(logger, "doCfcaAuth", "获取还绑卡验证码异常接口对象为空" + JSON.toJSONString(cstBank));
                    return new DataResultVO(BaseConstant.IS_YESNO_NO, "获取还绑卡验证码异常");
                } else {
                    if (messageDto.isSuccess()) {
                        BaseLogUtils.info(logger, "doCfcaAuth", "获取还绑卡验证码成功" + JSON.toJSONString(messageDto));
                        result.setSuccess(BaseConstant.IS_YESNO_YES);
                        result.setInfo("获取成功");
                    } else {
                        BaseLogUtils.info(logger, "doCfcaAuth", "获取还绑卡验证码失败" + JSON.toJSONString(messageDto));
                        result.setSuccess(BaseConstant.IS_YESNO_NO);
                        result.setInfo(messageDto.getMessage());
                    }

                }
                return result;
            }else{
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "四要素验证失败");
            }

        } catch (Exception e) {
            BaseLogUtils.info(logger, "doCfcaAuth", "获取验证码异常bankId = " + bankId + " ,Error：" + e.getMessage(), e);
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "获取验证码异常");
        }
    }

    @Override
    public DataResultVO changeCardBySMSCode(String cstId, String bankId, String smCode) throws BaseException {
        DataResultVO result = new DataResultVO(BaseConstant.IS_YESNO_YES, "成功!");
        if (StringUtils.isEmpty(cstId)) {
            BaseLogUtils.info(logger, "changeCardBySMSCode", "客户ID不能为空", CurrentThreadContext.getCurrentUserName());
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "客户ID未空");
        }
        if (StringUtils.isEmpty(bankId)) {
            BaseLogUtils.info(logger, "changeCardBySMSCode", "银行ID不能为空 cstId=" + cstId, CurrentThreadContext.getCurrentUserName());
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "银行ID未空");
        }
        if (StringUtils.isEmpty(bankId)) {
            BaseLogUtils.info(logger, "changeCardBySMSCode", "短信验证码不能为空 bankId=" + bankId, CurrentThreadContext.getCurrentUserName());
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "短信验证码未空");
        }
        try {
            List<Map<String, Object>> mapList = this.prjBscInfoService.selectChangeBankCardPrjPaySchInfo(null, Long.valueOf(cstId), PrjBscInfoConstant.PRJ_INS_CODE_ZS);
            if (CollectionUtils.isEmpty(mapList)) {
                BaseLogUtils.info(logger, "changeCardBySMSCode", "未获取浙商项目信息cstId = " + cstId, CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "未获取浙商项目信息");
            }
            Map<String, Object> prjMap = mapList.get(0);
            BaseLogUtils.info(logger, "changeCardBySMSCode", "查询获取接口所需数据 = " + cstId + "返回数据：" + JSON.toJSONString(prjMap), CurrentThreadContext.getCurrentUserName());
            if (StringUtils.isEmpty(String.valueOf(prjMap.get("PRJID")))) {
                BaseLogUtils.info(logger, "changeCardBySMSCode", "未获取浙商项目信息cstId = " + cstId, CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "未获取浙商项目信息");
            }
            Long prjId = Long.valueOf(String.valueOf(prjMap.get("PRJID")));
            if (StringUtils.isEmpty(String.valueOf(prjMap.get("PAYSCHID")))) {
                BaseLogUtils.info(logger, "changeCardBySMSCode", "未获取浙商项目支付表信息cstId = " + cstId, CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "未获取浙商项目支付表信息");
            }
            Long paySchId = Long.valueOf(String.valueOf(prjMap.get("PAYSCHID")));
            if (StringUtils.isEmpty(String.valueOf(prjMap.get("FUNDRASINSID")))) {
                BaseLogUtils.info(logger, "changeCardBySMSCode", "未获取浙商项目机构ID信息cstId = " + cstId, CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "未获取浙商项目机构ID信息");
            }
            Long fundRasInsId = Long.valueOf(String.valueOf(prjMap.get("FUNDRASINSID")));
            // 获取原卡信息
            PrjCstAccInfoQueryCondition prjAccQc = new PrjCstAccInfoQueryCondition();
            prjAccQc.setCstId(Long.valueOf(cstId));
            prjAccQc.setPrjId(prjId);
            prjAccQc.setInsCode(PrjBscInfoConstant.PRJ_INS_CODE_ZS);
            List<PrjCstAccInfoVO> prjCstAccInfoList = this.prjCstAccInfoService.searchList(prjAccQc);
            if (CollectionUtils.isEmpty(prjCstAccInfoList) || prjCstAccInfoList.size() == 0) {
                BaseLogUtils.info(logger, "changeCardBySMSCode", "未获取项目客户信息", CurrentThreadContext.getCurrentUserName());
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "未获取项目客户信息");
            }
            PrjCstAccInfoVO prjCstaccInfo = prjCstAccInfoList.get(0);
            BaseLogUtils.info(logger, "changeCardBySMSCode", "查询旧卡所需数据 = " + cstId + "返回数据：" + JSON.toJSONString(prjCstaccInfo), CurrentThreadContext.getCurrentUserName());
            //获取新卡信息
            CstBankQueryCondition cstBankQc = new CstBankQueryCondition();
            List<Long> cstIdList = new ArrayList<>();
            cstIdList.add(Long.valueOf(cstId));
            cstBankQc.setCstIdList(cstIdList);
            cstBankQc.setOrgCd(CurrentThreadContext.getCurrentOrgCd());
            cstBankQc.setSysCd(CurrentThreadContext.getCurrentSysCd());
            CstBankVO cstBank = this.cstBankService.selectById(Long.valueOf(bankId));
            BaseLogUtils.info(logger, "changeCardBySMSCode", "查询新卡所需数据 = " + cstId + "返回数据：" + JSON.toJSONString(cstBank), CurrentThreadContext.getCurrentUserName());
            MessageDTO messageDto = this.czbankApi.changeBankCard(fundRasInsId,prjId,paySchId,prjCstaccInfo.getAccNo(),cstBank.getAccNo(),smCode,bankId);
            if (null == messageDto) {
                BaseLogUtils.info(logger, "changeCardBySMSCode", "浙商短信验证码请求换绑卡异常 支付表id："+paySchId+"，bankid="+bankId);
                return new DataResultVO(BaseConstant.IS_YESNO_NO, "浙商短信验证码请求换绑卡异常");
            } else {
                if (messageDto.isSuccess()) {
                    BaseLogUtils.info(logger, "changeCardBySMSCode", "浙商短信验证码请求换绑卡成功" + JSON.toJSONString(messageDto));
                    result.setSuccess(BaseConstant.IS_YESNO_YES);
                    result.setInfo("换绑卡请求成功，请等待审核结果！");
                } else {
                    BaseLogUtils.info(logger, "changeCardBySMSCode", "浙商短信验证码请求换绑卡失败" + JSON.toJSONString(messageDto));
                    result.setSuccess(BaseConstant.IS_YESNO_NO);
                    result.setInfo(messageDto.getMessage());
                }
            }
            return result;

        } catch (Exception e) {
            BaseLogUtils.info(logger, "doCfcaAuth", "获取验证码异常bankId = " + bankId + " ,Error：" + e.getMessage(), e);
            return new DataResultVO(BaseConstant.IS_YESNO_NO, "获取验证码异常");
        }
    }

}
